package com.zff.rental.utils.collectors;

import java.io.Serializable;
import java.util.Comparator;
import java.util.Objects;
import java.util.function.Function;

/**
 * 比较器工具类
 *
 * @author HCY
 */
public class ComparatorUtils {
    /**
     * 比较Byte对象
     */
    public static int compare(Byte o1, Byte o2, boolean nullLast) {
        if (o1 == null && o2 == null) {
            return 0;
        } else if (o1 == null) {
            return nullLast ? 1 : -1;
        } else if (o2 == null) {
            return nullLast ? -1 : 1;
        }
        return Byte.compare(o1, o2);
    }

    /**
     * 比较Integer对象
     */
    public static int compare(Integer o1, Integer o2, boolean nullLast) {
        if (o1 == null && o2 == null) {
            return 0;
        } else if (o1 == null) {
            return nullLast ? 1 : -1;
        } else if (o2 == null) {
            return nullLast ? -1 : 1;
        }
        return Integer.compare(o1, o2);
    }

    /**
     * 比较String对象
     */
    public static int compare(String o1, String o2, boolean nullLast) {
        if (o1 == null && o2 == null) {
            return 0;
        } else if (o1 == null) {
            return nullLast ? 1 : -1;
        } else if (o2 == null) {
            return nullLast ? -1 : 1;
        }
        return o1.compareTo(o2);
    }

    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor, boolean nullLast) {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
                (c1, c2) -> {
                    U o1 = keyExtractor.apply(c1);
                    U o2 = keyExtractor.apply(c2);
                    if (o1 == null && o2 == null) {
                        return 0;
                    } else if (o1 == null) {
                        return nullLast ? 1 : -1;
                    } else if (o2 == null) {
                        return nullLast ? -1 : 1;
                    }
                    return o1.compareTo(o2);
                };
    }

    public static <T, U> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor, Comparator<? super U> keyComparator, boolean nullLast) {
        Objects.requireNonNull(keyExtractor);
        Objects.requireNonNull(keyComparator);
        return (Comparator<T> & Serializable)
                (c1, c2) -> {
                    U o1 = keyExtractor.apply(c1);
                    U o2 = keyExtractor.apply(c2);
                    if (o1 == null && o2 == null) {
                        return 0;
                    } else if (o1 == null) {
                        return nullLast ? 1 : -1;
                    } else if (o2 == null) {
                        return nullLast ? -1 : 1;
                    }
                    return keyComparator.compare(o1, o2);
                };
    }
}
